package com.llbnk.srb.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.llbnk.common.exception.Assert;
import com.llbnk.common.result.ResponseEnum;
import com.llbnk.srb.core.enums.UserBindEnum;
import com.llbnk.srb.core.hfb.FormHelper;
import com.llbnk.srb.core.hfb.HfbConst;
import com.llbnk.srb.core.hfb.RequestHelper;
import com.llbnk.srb.core.mapper.UserBindMapper;
import com.llbnk.srb.core.mapper.UserInfoMapper;
import com.llbnk.srb.core.pojo.entity.UserBind;
import com.llbnk.srb.core.pojo.entity.UserInfo;
import com.llbnk.srb.core.pojo.vo.UserBindVO;
import com.llbnk.srb.core.service.UserBindService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 用户绑定表 服务实现类
 * </p>
 *
 * @author llbnk
 * @since 2022-04-07
 */
@Service
public class UserBindServiceImpl extends ServiceImpl<UserBindMapper, UserBind> implements UserBindService {

    @Resource
    private UserInfoMapper userInfoMapper;

    @Override
    public String commitBindUser(UserBindVO userBindVO, Long userId) {

        /**
         * 这个项目要求借款人和投资人如果是一个card_id是不被允许的
         */
        QueryWrapper<UserBind> userBindQueryWrapper = new QueryWrapper<>();
        //判断如果身份证相同，但是user_info的user_id不同（user_id不同就是两条数据）
        userBindQueryWrapper
                .eq("id_card",userBindVO.getIdCard())
                .ne("user_id",userId);
        UserBind userBind = baseMapper.selectOne(userBindQueryWrapper);
        Assert.isNull(userBind, ResponseEnum.USER_BIND_IDCARD_EXIST_ERROR);

        /**
         * 假如用户已经在第三方平台登录并填写银行卡，身份证等等信息了
         * 然后突然关闭网页了，然后进入网页还需要填写这些银行卡，身份证什么什么的
         * （已经调用过了commitBindUser方法结果再次调用commitBindUser）
         * 此时因为之前已经插入了user_bind就造成了造成了重复
         * 所以需要我们在插入数据之前要判断一下是否是重复用户
         */

        //用户是否曾经填写过绑定表单
        userBindQueryWrapper = new QueryWrapper<>();
        userBindQueryWrapper.eq("user_id",userId);
        userBind = baseMapper.selectOne(userBindQueryWrapper);
        //如果之前没绑定过就绑定一个
        if (userBind == null){
            //创建用户绑定记录 往user_bind中插入数据
            userBind = new UserBind();
            //将userBindVO一样的字段信息拷贝到userBind中
            BeanUtils.copyProperties(userBindVO,userBind);
            //user_info user_bind user_account三个数据库都是一对一的关系
            //刚开始传进来的肯定还没绑定
            userBind.setUserId(userId);
            userBind.setStatus(UserBindEnum.NO_BIND.getStatus());
            baseMapper.insert(userBind);
        }
        //如果绑定过就修改之前的账户就可以了
        else {
            //相同的user_id,相同的身份证，如果存在，那么就取出数据，做更新
            BeanUtils.copyProperties(userBindVO,userBind);
            baseMapper.updateById(userBind);
        }



        //这个地方就是具体要提交的.html页面的代码了 我们需要使用hfb下面的buildForm HfbConst RequestHelper
        //来拼接这个form表单
        //表单格式如下：
        // <!DOCTYPE html>
        //<html lang="en" xmlns:th="http://www.thymeleaf.org">
        //  <head> </head>
        //  <body>
        //    <form name="form" action="远程地址" method="post">
        //      <!-- 参数 -->
        //      <input type="text" name="mobile" value="13900000000" />
        //      <input type="text" name="sign" value="123456" />
        //    </form>
        //    <script>
        //      document.form.submit()
        //    </script>
        //  </body>
        //</html>
        System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^^^^");
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //这个地方绑定信息，需要看第三方汇付平台的账户绑定怎么定义的，参考下面的3.3.3绑定账户请求
        //D:\学习类\java\金融项目--尚融宝\资料（ziw文件使用为知笔记打开）\资料\04第四部分\汇付宝
        //金融宝库被汇款宝库认领的的唯一ID
        paramMap.put("agentId", HfbConst.AGENT_ID);
        paramMap.put("agentUserId", userId);
        paramMap.put("idCard",userBindVO.getIdCard());
        paramMap.put("personalName", userBindVO.getName());
        paramMap.put("bankType", userBindVO.getBankType());
        paramMap.put("bankNo", userBindVO.getBankNo());
        paramMap.put("mobile", userBindVO.getMobile());
        paramMap.put("returnUrl", HfbConst.USERBIND_RETURN_URL);
        paramMap.put("notifyUrl", HfbConst.USERBIND_NOTIFY_URL);
        paramMap.put("timestamp", RequestHelper.getTimestamp());
        //签名，这也是srb传给hfb，hfb第一个检查的东西
        paramMap.put("sign", RequestHelper.getSign(paramMap));

        //生成动态表单字符串  FormHelper.buildForm(用户绑定汇付宝平台url地址,表单的提交项)
        String forStr = FormHelper.buildForm(HfbConst.USERBIND_URL, paramMap);
        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        System.out.println(forStr);
        System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
        return forStr;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void notify(Map<String, Object> paramMap) {

        //更新user_bind中的bind_code bind_status
        //param是hfb传给srb的
        String bindCode = (String)paramMap.get("bindCode");
        //会员id
        String agentUserId = (String)paramMap.get("agentUserId");

        //根据user_id查询user_bind记录
        QueryWrapper<UserBind> userBindQueryWrapper = new QueryWrapper<>();
        userBindQueryWrapper.eq("user_id",agentUserId);

        //更新用户绑定表user_bind
        UserBind userBind = baseMapper.selectOne(userBindQueryWrapper);
        userBind.setBindCode(bindCode);
        //状态设置为绑定成功
        userBind.setStatus(UserBindEnum.BIND_OK.getStatus());
        baseMapper.updateById(userBind);

        //更新用户表user_info
        //因为前面注册的时候只填写了手机号密码，像身份证，姓名都是用手机号替代的，所以此时我们需要把他们都填写完整
        UserInfo userInfo = userInfoMapper.selectById(agentUserId);
        userInfo.setBindCode(bindCode);
        userInfo.setName(userBind.getName());
        userInfo.setIdCard(userBind.getIdCard());
        //状态设置为绑定成功
        userInfo.setBindStatus(UserBindEnum.BIND_OK.getStatus());
        //注意：update时生成的sql自动是动态sql 他是根据这个类去查自动调用你这个类里面的id属性去查找
        userInfoMapper.updateById(userInfo);

    }

    @Override
    public String getBindCodeByUserId(Long userId){
        QueryWrapper<UserBind> userBindQueryWrapper = new QueryWrapper<>();
        userBindQueryWrapper.eq("user_id", userId);
        UserBind userBind = baseMapper.selectOne(userBindQueryWrapper);
        String bindCode = userBind.getBindCode();
        return bindCode;
    }
}
